Persistence Project

Persistence is an easy-to-use framework which supports multi-datasource, O-R Mapping and SQL-Mapping. The newest version could meet the needs of development of complex applications. The developers would spend less time on DAO modules.

Document

Log

The newest log has been changed for the requirement of Persistenc2.0, it includes:

  1. It supports 2 types which are simple log and complex log.
  2. It supports 5 basic types, the important level is fatal > error > warn > info > debug
  3. It supports 8 extend types, and includes : login, visit, dangerous-login, security, xss, sql-injection, img-hotlink, cookie-different-ip.
  4. It supports custom time format.
  5. It supports custom log folder.
  6. It supports classified storage.
  7. It supports min-level of log-to-file.
  8. It supports debug model , and min-level of log-to-console.

Configuration:

//show welcome words
welcome=false
//print in console
debug=true
//log folder path
logFolderPath=D:/log/
//custom date format
//dateFormat=yyyy-MM-dd HH:mm:ss:SSS
//log info in single line
singleLineLog=true
//the min level to show log in console
//leve:fatal > error > warn > info > debug
minLevel2Print=info
//the min level to record log in file
minLevel2File=warn

Code of java:

Logger logger = Logger.getInstance();
//simple model, no exception
logger.debug("[Test]" + info, null);
//simple model, has an exception
logger.error("[Test]" + info, new Exception("Error."));
//detail model, has an exception
LogData data = new LogData();
data.setUser("admin:tom")             //Not necessary
        .setSource("login.jsp")           //Not necessary
	.setCategory("security")          //Not necessary
	.setData("User name : tom . ")   //Not necessary
	.setDescription("Login error."); //Not necessary
logger.fatal(data, new Exception("Error."));  

 

Datasource

Datasource toolkit has been changed for the requirement of Persistence2.0. The ThreadLocal is used to manage connections.

Configuration:

<?xml version='1.0' encoding='UTF-8'?>
<Context>
	<DataSource name="mysql" type="javax.sql.DataSource">
		<parameter>
			<name>driverClass</name>
			<value>com.mysql.jdbc.Driver</value>
		</parameter>
		<parameter>
			<name>url</name>
			<value>jdbc:mysql://localhost:3306/platform</value>
		</parameter>
		<parameter>
			<name>user</name>
			<value>root</value>
		</parameter>
		<parameter>
			<name>pwd</name>
			<value></value>
		</parameter>
		<parameter>
			<name>associateConnectionPool</name>
			<value>true</value>
		</parameter>
		<parameter>
			<name>connectionPoolName</name>
			<value>mysqlpool</value>
		</parameter>
	</DataSource>
        <ConnectionPoolConfig name="mysqlpool">
		<parameter>
			<name>maxStatements</name>
			<value>20</value>
		</parameter>
		<parameter>
			<name>initialPoolSize</name>
			<value>10</value>
		</parameter>
		<parameter>
			<name>minPoolSize</name>
			<value>10</value>
		</parameter>
		<parameter>
			<name>maxPoolSize</name>
			<value>20</value>
		</parameter>
		<parameter>
			<name>maxidleTime</name>
			<value>3</value>
		</parameter>
		<parameter>
			<name>propertyCycle</name>
			<value>300</value>
		</parameter>
	</ConnectionPoolConfig>
</Context>

Code of java:

//The default datasource of Persistence2 framework is the first datasource in xml
String defaultDataSourceName = MultiConnectionPool.getInstance().getDefaultDataSourceName();

//Get connection from connection pool of default datasource
Connection conn1 = MultiConnectionPool.getInstance().getConnection(defaultDataSourceName);

// Get connection from connection pool by datasource name
Connection conn2 = MultiConnectionPool.getInstance().getConnection(“test”);

 

ORM Rules

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<object-sql-mapping>
		<object>
			>class>com.nonesole.web.platform.sys.User>/class>
			<table>sys_user </table>
			<primery-key>id</primery-key>
		</object>
		<object>
			<class>com.nonesole.web.platform.sys.Role>/class>
			<table>sys_role</table>
			<primery-key>id</primery-key>
		</object>	
		<object>
			<class>com.nonesole.web.platform.sys.UserRole>/class>
			<table>sys_user_role</table>
			<primery-key/>
		</object>
	</object-sql-mapping>
</config>

Description:

  • <object-sql-mapping> is proper tag of ORM.
  • <object> is a tag which means whole relationship of ORM.
  • <class> is a tag of class name.
  • <table> is a tag of table name.
  • <primery-key> is a tag of primery-key.

 

ORM-PLUS Rules

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<actions>
		<action name="findUserById" transaction="true">
			<orm-action>select</orm-action>
			<input>
				<object property="orm-pojo">
					<mapping>
						<source>
							<where>true</where>
							<name>id</name>
							<class>int</class>
							<not-null>true</not-null>
						</source>
						<target/>
					</mapping>
				</object>
			</input>
			<output>
				<object property="pojo-list">
					<object-class>java.util.ArrayList</object-class>
					<item-class>com.nonesole.web.platform.sys.User </item-class>
					<mapping>
						<source>
							<name>name</name>
						</source>
						<target>
							<name>name</name>
							<class>String</class>
						</target>
					</mapping>
				</object>
			</output>
		</action>
	</actions>
</config>

Description:

  • <actions> is a proper tag of ORM-PLUS Rules and SQL-MAPPING Rules.
  • <action> is a tag means this configuration equals a DAO method. transaction attribute means whether or not the current action is a whole transaction.
  • <orm-action> is a proper tag of ORM-PLUS Rules only. The operators are:
    1. insert : Save part of object.
    2. update : Update part of object. The operator 'where' sql is '=' and the relation of conditions is 'and'.
    3. delete : Delete object by 'where' sql which is as same as upate operator.
    4. select : Search objects by 'where' sql which is as same as upate operator.
  • <input> is a tag for input-parameter of action.
  • <object> is a subtag of input tag.Under ORM-PLUS Rules, it includes:
    1. orm-pojo : The input-parameter is POJO which is for ORM-PLUS Rules.
    2. orm-pojo-list : The input-parameter is list of POJO which is for ORM-PLUS Rules.
  • <mapping> is a tag which is used to build relationship between fields in object and columns of table. Under ORM-PLUS Rules, it just needs <source> tag.
  • <source> is a tag for data-types of parameter.It includes 7 types:
    1. <name> is a tag for field name of object.
    2. <class> is a tag for field type of object.
    3. <not-null> is a tag for checking whether or not field value is allowed to be null.
    4. <default-value> is a tag for default value of field.If <not-null> is true and input value is null, the default value will be used.
    5. <min-value> is a tag for setting min-value of field value.
    6. <max-value> is a tag for setting max-value of field value.
    7. <where> is a proper tag of ORM-PLUS Rules only. It is used to mark this mapping configuration would be used in 'where' sql.
  • <output> is a tag for return value.
  • <object> is a subtag of output tag.Under ORM-PLUS Rules, it includes:
    1. pojo-list : The output-value of action is list of POJO.
  • <object-class> is a subtag of output tag.It means the type of return value.
  • <item-class> If <output> is List object,just like java.util.ArrayList, this tag means the type of object in the list.
  • <mapping> is a tag which is used to build relationship between columns of ResultSet and fields of object.
  • <source> is a subtag of mapping tag and it is for columns of ResultSet.
    1. <name> is a tag for column name.
  • <target> is a tag for each field of object, it includes:
    1. <name> is a tag for field name of object.
    2. <class> is a tag for field type of object.

 

SQL-MAPPING Rules

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<actions>
		<action name="findUsersByAge" transaction="true">
			<input>
				<object property="map">
					<mapping>
						<source>
							<name>age</name>
							<class>int</class>
							<not-null>true</not-null>
						</source>
						<target>
							<name>//age</name>
						</target>
					</mapping>
				</object>
			</input>
			<output>
				<object property="pojo-list">
					<object-class>java.util.ArrayList</object-class>
					<item-class>com.nonesole.web.platform.sys.User </item-class>
					<mapping>
						<source>
							<name>name</name>
						</source>
						<target>
							<name>name</name>
							<class>String</class>
						</target>
					</mapping>
				</object>
			</output>
			<sql>select * from user where age>//age</sql>
		</action>
	</actions>
</config>

Description:The configuration which is as same as the ORM-PLUS rules would be not explained here.

  • <object> is a subtag of input tag.Under SQL-MAPPING Rules, it includes:
    1. simple-list : The input-parameter is is list of single-value, just like List<Integer>.
    2. pojo : The input-parameter is is POJO.
    3. pojo-list : The input-parameter is list of POJO, just like List<User>.
    4. map : The input-parameter is is map, just like HashMap.
  • <mapping> is a subtag of input tag. Under SQL-MAPPING Rules ,the <source> tag and <target> tag must be set. But the <sql-part> tag should be set on needs.
  • <sql-part> is a dedicated tag for SQL-MAPPING Rules. In general, it is not allowed to edit prepared sql by code of application. But in special cases, the developer must do that. The <sql-part> tag is the switch for sql-editing.
  • <target> is a subtag of input tag.
    1. <name> is a subtag of target tag. It is the mark in sql, and it would be replaced by the value of field.
  • <object> is a subtag of output tag. It is for return value. Under SQL-MAPPING Rules, it includes:
    1. void : There is no return value.
    2. simple : The return value is single-value object, just like Integer,Double,String.
    3. simple-list: The return value is list of single-value object, just like List<Integer>
    4. pojo : The return value is POJO.
    5. pojo-list : The return value is list of POJO.
    6. map-list : The return value is list of map, just like List<Map<String,Object>>
  • <sql> is a tag for SQL.It consists of two pieces: SQL and input-value-marks which will be replaced on executing.

 

Save object (all fields)

Configuration (The primery-key tag could be null if there is no primery-key on table)

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<object-sql-mapping>
		<object>
			<class>com.nonesole.web.platform.sys.User</class>
			<table>sys_users </table>
			<primery-key>id</primery-key>
		</object>
	</object-sql-mapping>
</config>

Code:

User u = new User();
u.setName("tom");
……
IOrmAction action = PersistenceFactory.getInstance().getOrmAction();
action.insert(u);
System.out.println(u.getId());

 

Batch save objects (all fields)

The configuration is as the same as the 'Save object(all fields)' chapter.

Code:

List<User> users = new ArrayList<User>();
users.add(…);
IOrmAction action = PersistenceFactory.getInstance().getOrmAction();
action. action.batchInsert(users);

 

Save object (part of fields)

The best solution is ORM-PLUS Rules.

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<config>
<actions>
	<action name="saveUser" transaction="true">
		<orm-action>insert</orm-action>
		<input> 
			<object property="orm-pojo">
				<mapping> 
					<source>
						<name>name</name>
						<class>java.lang.String</class>
						<not-null>true</not-null>
						<default-value/>
						<min-length>2</min-length>
						<max-length>20</max-length>
					</source>
					<target/>
				</mapping>
			</object>
		</input> 
		<output></output>
	</action>
</actions>
</config>

Code:

User u = new User();
u.setName("tom");
……
IOrmPlusAction action = PersistenceFactory.getInstance().getOrmPlusAction();
action.doAction("saveUser", u);
System.out.println(u.getId());

 

Batch save objects (part of fields)

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<config>
<actions>
	<action name="batchSaveUser" transaction="true">
		<orm-action>insert</orm-action>
		<input> 
			<object property="orm-pojo-list">
				<mapping> 
					<source>
						<name>name</name>
						<class>java.lang.String</class>
						<not-null>true</not-null>
						<min-length>2</min-length>
						<max-length>20</max-length>
					</source>
					<target/>
				</mapping>
			</object>
		</input> 
		<output></output>
	</action>
</actions>
</config>

Code:

List<User> users = new ArrayList<User>();
users.add(…);
IOrmPlusAction action = PersistenceFactory.getInstance().getOrmPlusAction();
action.doAction("batchSaveUser ", users);

 

Save objects with sql

Use SQL-MAPPING Rules

Configuration:

<config>
<actions>
	<action name="createTempTable" transaction="true">
		<input/> 
		<output/>
		<sql>insert into temp(id,name) select id,name from user</sql>  
	</action>
</actions>
</config>

Code:

IVoidAction action = PersistenceFactory.getInstance().getVoidAction();
action.doAction("createTempTable", null);

Use ORM Rules

Code:

IOrmAction action = PersistenceFactory.getInstance().getOrmAction();
action.execute("insert into temp(id,name) select id,name from user");

 

Update object (all fields)

Configuration(The primery-key can not be null.):

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<object-sql-mapping>
		<object>
			<class>com.nonesole.web.platform.sys. User</class>
			<table>sys_users</table>
			<primery-key>id</primery-key>
		</object>
	</object-sql-mapping>
</config>

Code:

User u = new User();
u.setId(10);
u.setName("tom");
……
IOrmAction action = PersistenceFactory.getInstance().getOrmAction();
action.update(u);

 

Batch update objects (all fields)

The Configuration is as the same as the 'Update object (all fields)' capter. Code:

List<User> users = new ArrayList<User>();
users.add(…);
IOrmAction action = PersistenceFactory.getInstance().getOrmAction();
action. action.batchUpdate(users);

 

Update object (part of fields)

Use ORM-PLUS Rules

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<actions>
		<action name="updateUser" transaction="true">
			<orm-action>update</orm-action>
			<input> 
				<object property="orm-pojo">
					<mapping>
						<source>
							<where>true</where>
							<name>id</name>
							<class>int</class>
							<not-null>true</not-null>
						</source>
						<target/>
					</mapping>
					<mapping> 
						<source>
							<name>name</name>
							<class>java.lang.String</class>
							<not-null>true</not-null>
						</source>
						<target/>
					</mapping>
				</object>
			</input> 
			<output></output>
		</action>
	</actions>
</config>

Code:

User u = new User();
u.setId(8);
u.setName("tom");
IOrmPlusAction action =  PersistenceFactory.getInstance().getOrmPlusAction();
action.doAction("updateUser", u);

Use SQL-MAPPING Rules

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<actions>
		<action name="updateUser" transaction="true">
			<input> 
				<object property="map">
					<mapping>
						<source>
							<name>id</name>
							<class>int</class>
						</source>
						<target>
							<name>//id</name>
						</target>
					</mapping>
					<mapping>
						<source>
							<name>name</name>
							<class>String</class>
						</source>
						<target>
							<name>//name</name>
						</target>
					</mapping>
				</object>
			</input> 
			<output></output>
			<sql>
				update user set name=//name where id=//id and not exist 
				(select 1 from (select 1 from user_role where user_id=//id) t1 )
			</sql>
		</action>
	</actions>
</config>

Code:

Map map = new HashMap();
map.put("id",10);
map.put("name","tom");
……
IVoidAction action = PersistenceFactory.getInstance().getVoidAction();
action.doAction("updateUser ", map);

 

Delete object

Configuration:(The primery-key can not be null.)

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<object-sql-mapping>
		<object>
			<class>com.nonesole.web.platform.sys.user.User</class>
			<table>sys_users_login</table>
			<primery-key>id</primery-key>
		</object>
	</object-sql-mapping>
</config>

Code:

User u = new User();
u.setId(10);
……
IOrmAction action = PersistenceFactory.getInstance().getOrmAction();
action.delete(u);

 

Batch delete objects

The configuration is as the same as the 'Delete object' capter.

Code:

List<User> users = new ArrayList<User>();
users.add(…);
IOrmAction action = PersistenceFactory.getInstance().getOrmAction();
action. action.batchDelete(users);

 

Delete with complex condition

Use ORM-PLUS Rules

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<config>
<actions>
	<action name="deleteUser" transaction="true">
		<orm-action>delete</orm-action>
		<input> 
			<object property="orm-pojo">
				<mapping>
					<source>
						<where>true</where>
						<name>id</name>
						<class>int</class>
						<not-null>true</not-null>
					</source>
					<target/>
				</mapping>
				<mapping> 
					<source>
						<where>true</where>
						<name>name</name>
						<class>java.lang.String</class>
						<not-null>true</not-null>
					</source>
					<target/>
				</mapping>
			</object>
		</input> 
		<output></output>
	</action>
</actions>
</config>

Code:

User u = new User();
u.setName("tom");
……
IOrmPlusAction action = PersistenceFactory.getInstance().getOrmPlusAction();
action.doAction("updateUser", u);

Use SQL-MAPPING Rules

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<config>
<actions>
	<action name="deleteUser" transaction="true">
		<input> 
			<object property="map">
				<mapping>
					<source>
						<name>id</name>
						<class>int</class>
					</source>
					<target>
						<name>//id</name>
					</target>
				</mapping>
			</object>
		</input> 
		<output></output>
		<sql>delete from user_role where user_id=//id</sql>
		<sql>delete from user where id=//id </sql>
	</action>
</actions>
</config>

Code:

Map map = new HashMap();
map.put("id",10);
……
IVoidAction action = PersistenceFactory.getInstance().getVoidAction();
action.doAction("updateUser ", map);

 

Query with no condition

Use ORM Rules

Code:

IOrmAction action = PersistenceFactory.getInstance().getOrmAction();
List<Object> users = action.execute("select * from user",User.class);

Use ORM-PLUS Rules

Configuration:

	<action name="findUsers" transaction="true">
		<orm-action>select</orm-action>
		<input></input> 
		<output>
			<object property="pojo-list">
			<object-class>java.util.ArrayList</object-class>
			<item-class>com.nonesole.User</item-class>
				<mapping>
					<source>
						<name>name</name>
					</source>
					<target>
						<name>name</name>
						<class>String</class>
					</target>
				</mapping>
			</object>
		</output>
	</action>

Code:

IOrmPlusAction action = 
PersistenceFactory.getInstance().getOrmPlusAction();
List<Object> users = action. doQueryAction ("findUsers ", new User());

Use SQL-MAPPING Rules

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<config>
<actions>
	<action name="findUsers" transaction="true">
		<input></input> 
		<output>
			<object property="pojo-list">
				<object-class>java.util.ArrayList</object-class>
				<item-class>com.nonesole.User</item-class>
				<mapping>
					<source>
						<name>name</name>
					</source>
					<target>
						<name>name</name>
						<class>String</class>
					</target>
				</mapping>
			</object>
		</output>
		<sql>select * from user</sql>
	</action>
</actions>
</config>

Code:

IPojoAction<User> action = 
PersistenceFactory.getInstance().getPojoAction();
List<User> users = action. pojoListAction ("findUsers", null);

 

Query with simple condition

Use ORM Rules

We do not advise to use the rules , bucause it is not for PreparedStatement.

Use ORM-PLUS Rules

Configuration:

	<action name="findUsers" transaction="true">
		<orm-action>select</orm-action>
		<input>
			<object property="orm-pojo">
				<mapping>
					<source>
						<where>true</where>
						<name>id</name>
						<class>int</class>
						<not-null>true</not-null>
					</source>
					<target/>
				</mapping>
			</object>
		</input> 
		<output>
			<object property="pojo-list">
				<object-class>java.util.ArrayList</object-class>
				<item-class>com.nonesole.User</item-class>
				<mapping>
					<source>
						<name>name</name>
					</source>
					<target>
						<name>name</name>
						<class>String</class>
					</target>
				</mapping>
			</object>
		</output>
	</action>

Code:

User user = new User();
user.setAge(18);
IOrmPlusAction action = PersistenceFactory.getInstance().getOrmPlusAction();
List<User> users = action. doQueryAction ("findUsers ", user);

Use SQL-MAPPING Rules

Configuration:

	<action name="findUsers" transaction="true">
		<input>
			<object property="map">
				<mapping>
					<source>
						<name>age</name>
						<class>int</class>
						<not-null>true</not-null>
					</source>
					<target>
						<name>//age</name>
					</target>
				</mapping>
			</object>
		</input> 
		<output>
			<object property="pojo-list">
				<object-class>java.util.ArrayList</object-class>
				<item-class>com.nonesole.User</item-class>
				<mapping>
					<source>
						<name>name</name>
					</source>
					<target>
						<name>name</name>
						<class>String</class>
					</target>
				</mapping>
			</object>
		</output>
		<sql>select * from user where age=//age</sql>
	</action>

Code:

Map<String,Object> map = new HashMap<String,Object>();
map.put("age",18);
IPojoAction<User> action = 
PersistenceFactory.getInstance().getPojoAction();
List<User> users = action. pojoListAction ("findUsers", map);

 

Query with complex condtion

Use PreparedStatement

Configuration:

	<action name="findUsers" transaction="true">
		<input>
			<object property="map">
				<mapping>
					<source>
						<name>start_index</name>
						<class>int</class>
						<not-null>true</not-null>
						<default-value>1</default-value>
					</source>
					<target>
						<name>//start_index</name>
					</target>
				</mapping>
				<mapping>
					<source>
						<name>condition</name>
						<class>java.lang.String</class>
						<not-null>false</not-null>
					</source>
					<target>
						<name>//condition</name>
					</target>
					<sql-part>true</sql-part>
				</mapping>
			</object>
		</input>
		<output>				
			<object property="pojo-list">
				<object-class>java.util.ArrayList</object-class>
				<item-class>com.nonesole.User</item-class>
				<mapping>
					<source>
						<name>name</name>
					</source>
					<target>
						<name>name</name>
						<class>java.lang.String</class>
					</target>
				</mapping>
			</object>
		</output>
		<sql>
			select * from sys_users_login //condition 
			order by id desc limit //start_index,10
		</sql>
	</action>

Code:

Map<String,Object> map = new HashMap<String,Object>();
map.put("start_index ",1);
map.put("//condition", "where (name like //name// and nick_name like //name//)");
map.put("//name//","%tom%");
IPojoAction<User> action = PersistenceFactory.getInstance().getPojoAction();
List<User> users = action. pojoListAction ("findUsers", map);

Use ORM Rules(Not PreparedStatement)

No configuration.Just code:

String sql = "select * from user where age > " + 18;
IOrmAction action = PersistenceFactory.getInstance().getOrmAction();
List<Object> users = action.execute(sql,User.class);

Use SQL-MAPPING Rules(Not PreparedStatement)

Configuration:

	<action name="findUsers" transaction="true">
		<input>
			<object property="map">
				<mapping>
					<source>
						<name>condition</name>
						<class>java.lang.String</class>
						<not-null>false</not-null>
					</source>
					<target>
						<name>//condition</name>
					</target>
				</mapping>
			</object>
		</input>
		<output>				
			<object property="simple-list">
				<mapping>
					<source> 
						<name>id</name>
					</source>
					<target>
						<class>int</class>
					</target>
				</mapping>
			</object>
		</output>
		<sql>select id from sys_users_login //condition order by id desc</sql>
	</action>

Code1:

Map<String,Object> map = new HashMap<String,Object>();
map.put("condition", "where age > 18");

Connection conn = PersistenceFactory.getInstance().getDefaultConnection();

IArrayValueAction action = PersistenceFactory.getInstance().getArrayValueAction();
//It is not prepared statement
Integer[] id = action. intArrayAction ("findUser", map, conn, false);

Code2:

Map<String,Object> map = new HashMap<String,Object>();
map.put("condition", "where age > 18");

Connection conn = PersistenceFactory.getInstance().getDefaultConnection();

IListValueAction action = PersistenceFactory.getInstance().getListValueAction ();
//It is not prepared statement
List<Integer> id = action. intListAction ("findUser", map, conn, false);

 

Tansaction by configuration

Configuration:

<action name="deleteUser" transaction="true">
	……
	<sql>delete from user_role where user_id=//id</sql>
	<sql>delete from user where id=//id</sql>
	<sql>insert into log(…) values(…)</sql>
</action>

Code:

Map<String,Object> map = new HashMap<String,Object>();
map.put("id", 10);
……
IVoidAction action = PersistenceFactory.getInstance().getVoidAction();
action.doAction("deleteUser", map);

 

Tansaction by code

Configuration:

<action name="deleteUserRelation" transaction="false">
	……
	<sql>delete from user_role where user_id=//id</sql>
</action>
<object-sql-mapping>
	<object>
		<class>com.nonesole.web.platform.sys.User</class>
		<table>sys_users </table>
		<primery-key>id</primery-key>
	</object>
	<object>
		<class>com.nonesole.web.platform.sys.Log</class>
		<table>sys_log</table>
		<primery-key>id</primery-key>
	</object>
</object-sql-mapping>

Code:

PSession ps = new PSession();

Map<String,Object> map = new HashMap<String,Object>();
……
ps.voidAction("deleteUserRelation", map);

User u = new User();
u.setId(10);
ps.delete(u);

Log log = new Log();
log.setText("error.");
ps.insert(log);

ps.commit();